from typing import Union, List, Optional

from fastapi import APIRouter, Depends, Body, Header, Query, Request
from fastapi.encoders import jsonable_encoder
from odoo.api import Environment
from odoo.addons.fastapi.dependencies import odoo_env
from ...functions.router_fuc import RouterFunc
from ...basemodels.dto.order.step_model import StepOne, StepTwo, StepThree, StepFour, StepFive, EditAddress, StepSix
from ...basemodels.dto.order.common_model import MailRouteFilter
from ...basemodels.vo.common.trd_level import Country, PackageType, Courier, ValueAdded, Aging
from ...basemodels.vo.common.sec_level import PostCode
from ...basemodels.vo.common.first_level import RpShipOrder
from odoo.addons.fastapi_odoo_bridge.core.response import custom_response
from odoo.addons.fastapi_odoo_bridge.core.header import set_lang
from odoo.addons.fastapi_odoo_bridge.core.basemodel import CommonResponse

router = APIRouter(tags=['订单'])

"""
Belong:新UI
Description:下单表现层
"""

"""
Common Interface
"""


@router.get(
    path='/get/order/detail',
    summary='此接口只用于获取游客的相关数据',
    description='此接口只用于获取游客的相关数据',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
async def get_order_detail(order_code: str = Query(..., alias='order_code', description='订单编码'), env: Environment = Depends(odoo_env)):
    func = RouterFunc(env)
    result = func.get_order_detail(order_code)
    if not isinstance(result, dict):
        rp_ship_order = RpShipOrder(__from_odoo=result, __env=env)
        # 填充所有所有增值服务明细
        all_available_value_added = RouterFunc(env).get_all_available_value_added(rp_ship_order.shipper_mail_route.id)
        rp_ship_order.available_value_added_list = all_available_value_added
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=rp_ship_order))
    return result


@router.get(
    path='/discard/order',
    summary='逻辑删除订单',
    description='逻辑删除订单',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
async def logic_delete_order(order_code: str = Query(..., alias='order_code', description='订单编码'), env: Environment = Depends(odoo_env)):
    func = RouterFunc(env)
    result = func.logic_delete_order(order_code)
    return result


"""
RELATED NEW UI STEP ONE
"""


@router.get(
    path='/get/country',
    summary='获取国家数据',
    description='根据输入框中的国家进行模糊搜索',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_country(country_name: str = Query(None, alias='country_name', description='国家名称'), env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.get_country_list(country_name)
    if not isinstance(result, dict):
        result = [Country(__from_odoo=record, __env=env) for record in result]
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


@router.get(
    path='/get/postcode',
    summary='获取邮编',
    description='国家ID必须传递,输入框中可以输入邮编或城市名称，展示前10条',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_postcode(country_id: int = Query(..., alias='country_id', description='国家ID'),
                       postcode_city: str = Query(None, alias='postcode_city', description='邮编或城市'),
                       env: Environment = Depends(odoo_env),
                       Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.get_postcode(country_id, postcode_city)
    if not isinstance(result, dict):
        result = [PostCode(__from_odoo=record, __env=env) for record in result]
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
        return result
    return result


@router.get(
    path='/get/package_type',
    summary='获取包裹类型',
    description='获取包裹类型',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_package_type(env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.get_package_type()
    if not isinstance(result, dict):
        result = [PackageType(__from_odoo=record, __env=env) for record in result]
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


"""
RELATED NEW UI STEP TWO
"""


@router.get(
    path='/get/all/courier',
    description='获取所有承运商数据',
    summary='获取所有承运商数据',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_all_courier(env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.get_all_courier()
    if not isinstance(result, dict):
        result = [Courier(__from_odoo=record, __env=env) for record in result]
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


@router.get('/get/all/aging',
            summary='获取所有时效',
            description='获取所有时效',
            response_model=Union[list, dict, List[dict]])
@custom_response
@set_lang
async def get_all_aging(Accept_Language: Optional[str] = Header(), env: Environment = Depends(odoo_env)):
    # 时效
    result = env['rp.aging'].search([])
    if not isinstance(result, dict):
        result = [Aging(__from_odoo=record, __env=env) for record in result]
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


@router.post(
    path='/filter/available/route',
    summary='筛选或获取可用邮路',
    description='如果没有传递筛选条件，默认为获取可用邮路',
    response_model=Union[list, dict, List[dict]])
@custom_response
@set_lang
async def filter_available_mail_route(route_filter: MailRouteFilter = Body(None, description='邮路筛选条件'),
                                      Accept_Language: Optional[str] = Header(), env: Environment = Depends(odoo_env)):
    func = RouterFunc(env)
    response = func.filter_available_mail_route(route_filter)
    return response


"""
RELATED NEW UI STEP THREE
"""


@router.get(
    path='/get/all/value_added',
    summary='获取所有增值服务',
    description='获取所有增值服务',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_all_value_added(env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.get_all_value_added()
    if not isinstance(result, dict):
        result = [ValueAdded(__from_odoo=record, __env=env) for record in result]
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


"""
RELATED NEW UI STEP FIVE
"""


@router.post(
    path='/edit/address_data',
    summary='修改地址信息',
    description='新UI第五步修改地址信息',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def edit_address(edit_address: EditAddress = Body(..., description='编辑地址'), env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.edit_address(edit_address)
    return result


"""
NEW UI STEP ONE
细分两步
"""


@router.post(
    path='/order/step1',
    description='下单步骤1【属于新UI的第一步】',
    summary='添加收发件国家，邮编以及包裹类型，自动触发请求',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def order_step1(request: Request, step_one: StepOne = Body(..., description='步骤一数据'), env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    # 用户登录后从session中获取用户ID
    login_user = request.session.get('order_customer_id')
    func = RouterFunc(env)
    response = func.order_step_one(login_user=login_user, from_country=step_one.from_country, to_country=step_one.to_country, from_city_postal_code=step_one.from_city_postal_code,
                                   to_city_postal_code=step_one.to_city_postal_code, package_type=step_one.package_type, edit_tag=step_one.edit_tag, order_code=step_one.order_code)
    if not isinstance(response, dict):
        ship_order = RpShipOrder(__from_odoo=response, __env=env)
        response = jsonable_encoder(CommonResponse(code='200', msg='success', data=ship_order))
    return response


@router.post(
    path='/order/step2',
    description='下单步骤2',
    summary='添加包裹信息，在第二步中可以修改第一步的数据',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def order_step2(env: Environment = Depends(odoo_env),
                      step_two: StepTwo = Body(..., description='下单步骤2', alias='step_two'),
                      Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    response = func.order_step_two(order_code=step_two.order_code, parcel_list=step_two.parcel_list, edit_tag=step_two.edit_tag)
    if not isinstance(response, dict):
        result = RpShipOrder(__from_odoo=response, __env=env)
        response = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return response


"""
NEW UI STEP TWO
"""


@router.post(
    path='/order/step3',
    summary='选择指定邮路',
    description='选择指定邮路并添加至订单',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def order_step3(env: Environment = Depends(odoo_env),
                      step_three: StepThree = Body(..., description='选中的邮路ID'),
                      Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result, value_added_list = func.order_order_three(step_three.order_code, step_three.mail_route_id, step_three.edit_tag)
    if not isinstance(result, dict):
        result = RpShipOrder(__from_odoo=result, __env=env)
        result.available_value_added_list = value_added_list
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


"""
NEW UI STEP THREE
"""


@router.post(
    path='/order/step4',
    summary='填充包裹详细信息和增值服务',
    description='填充包裹详细信息和增值服务',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def order_step4(env: Environment = Depends(odoo_env),
                      step_four: StepFour = Body(..., description='下单步骤四'),
                      Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.order_step4(step_four)
    if not isinstance(result, dict):
        result = RpShipOrder(__from_odoo=result, __env=env)
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


"""
NEW UI STEP FOUR
"""


@router.post(
    path='/order/step5',
    description='下单步骤5 填写地址信息',
    summary='下单步骤5 填写地址信息',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def order_step5(env: Environment = Depends(odoo_env),
                      step_five: StepFive = Body(..., description='下单步骤五'),
                      Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    result = func.order_step5(step_five)
    if not isinstance(result, dict):
        result = RpShipOrder(__from_odoo=result, __env=env)
        result = jsonable_encoder(CommonResponse(code='200', msg='success', data=result))
    return result


"""
RELATED NEW UI STEP FIVE
"""


@router.post(
    path='/order/step6',
    description='下单步骤六【支付】',
    summary='下单步骤六',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def order_step6(step_six: StepSix = Body(..., description='支付参数'),
                      env: Environment = Depends(odoo_env),
                      Accept_Language: Optional[str] = Header()):
    func = RouterFunc(env)
    response = func.order_step6(step_six)
    if not isinstance(response, dict):
        response = jsonable_encoder(CommonResponse(code='200', msg='success', data=response))
    return response
